/*
 * $Id: MultiPartFileUploadController.java,v 1.15 2012/02/15 15:08:29 navdeep_mahajan Exp $
 * 
 * Copyright (C) 2008 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.onwatch.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.ASCUtil;
import com.ge.healthcare.autosc.common.database.pojo.HstSystemContactInfo;
import com.ge.healthcare.autosc.common.dbLogger.ContactLogger;
import com.ge.healthcare.autosc.onwatch.bean.FileUploadBean;
import com.ge.healthcare.autosc.onwatch.exception.OnWatchException;
import com.ge.healthcare.autosc.onwatch.pojo.ErrorCode;
import com.ge.healthcare.autosc.onwatch.util.OnWatchConstants;
import com.ge.healthcare.autosc.onwatch.util.ResourceBundleUtil;

/**
 * MultiPartFileUploadController is the HTTP controller for file upload request.
 * This controller accepts both prodiags and status report file upload.
 * <i>(Please refer to Onwatch receiver design for details)</i>
 * 
 * Controller will redirect to Error View for error condition.
 * 
 * @author 212042946
 * 
 */
public class MultiPartFileUploadController extends AbstractFormController {

	/**
	 * Init method (Spring init)
	 */
	public void init() {
		super.init();
	}

	/**
	 * Override onSubmit from superclass
	 */
	protected ModelAndView onSubmit(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws ServletException, IOException {
		String methodName = "onSubmit";
		ASCLogger.debug(this.getClass(), methodName, "On Submit called...");
		ContactLogger.startLogging(request.getRemoteAddr(),
				HstSystemContactInfo.HTTP_CONNECT_TYPE);
		ContactLogger.addContactLog("File upload request");
		FileUploadBean fileUploadBean = (FileUploadBean) command;
		ASCLogger.info(this.getClass(), methodName, "Process request\n"
				+ fileUploadBean);
		fileUploadBean.setRemoteAddr(request.getRemoteAddr());
		checkSimulatorRequest(fileUploadBean);

		MultipartFile uploadFile = fileUploadBean.getFile();
		ModelAndView mav = null;
		try {
			if (fileUploadBean.isProdiagsRequest()) {
				// Prodiags File Upload request
				getOnWatchService().fileUploadForNewTask(fileUploadBean);
			} else {
				getOnWatchService().fileUploadForExistingTask(fileUploadBean);
			}
		} catch (OnWatchException owe) {
			ErrorCode errorCode = new ErrorCode(this.getClass().getName());
			errorCode.addCode("failed.upload.detail");
			errorCode.AddErrorCodeAsArgument(getCodeDetailsDAO(),
					owe.getErrorCode());
			errors.addError(errorCode.getObjectError("File upload failed"));
			mav = callError(request, response, errors);
		} catch (Throwable e) {
			ASCLogger.debug(this.getClass(), methodName, "get throwable ", e);
			ErrorCode errorCode = new ErrorCode(this.getClass().getName());
			errorCode.addCode("error.system.internal");
			errors.addError(errorCode.getObjectError("Internal System error"));
			mav = callError(request, response, errors);
		} finally {
			// Close the inputStream regardless
			uploadFile.getInputStream().close();
			ContactLogger.endLogging(null);
		}
		return mav;
	}

	/**
	 * Override showForm from superclass
	 */
	protected ModelAndView showForm(HttpServletRequest request,
			HttpServletResponse response, BindException errors)
			throws Exception {
		String methodName = "showForm";
		boolean validationError = false;
		// This is from validation failure, which is not called from onSubmit
		if (!ContactLogger.hasLoggingStarted()) {
			ContactLogger.startLogging(request.getRemoteAddr(),
					HstSystemContactInfo.HTTP_CONNECT_TYPE);
			validationError = true;
		}
		ASCLogger.debug(this.getClass(), methodName, "In showForm....");
		ModelAndView mav = null;
		if (errors.hasErrors()) {
			super.logErrors(errors);
			Map<Object, Object> model = new HashMap<Object, Object>();
			/*
			 * If multiple errors, this comes from validation or binding. Only
			 * give remote system the first failed error when remote system
			 * suppose to know how to communicate.
			 */
			ObjectError err = (ObjectError) errors.getAllErrors().get(0);
			String errorMessage = ResourceBundleUtil.getMessage(
					OnWatchConstants.ONWATCH_MESSAGE_BASENAME, err.getCode(),
					err.getArguments(), err.getDefaultMessage(), null);
			ContactLogger.addContactLog("Error message: " + errorMessage);
			model.put("error", errorMessage);
			model.put("systemId", request.getParameter("systemId"));
			model.put("iipVersion", request.getParameter("iipVersion"));
			mav = new ModelAndView("errorView", model);
		}
		// End the logging here
		if (validationError) {
			ContactLogger.endLogging(null);
		}
		return mav;
	}

	/**
	 * Read from request headers instead of doGet and doPost
	 * 
	 * @see org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest)
	 */
	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {
		String methodName = "formBackingObject";
		FileUploadBean bean = (FileUploadBean) super.formBackingObject(request);
		// Old school uploads won't have anything in header and super call would
		// have taken care of it
		if (!ASCUtil.isNullOrEmpty(request.getHeader("iipVersion"))) {
			bean.setIipVersion(request.getHeader("iipVersion"));
			bean.setSystemId(request.getHeader("systemId"));
			bean.setRequestType(request.getHeader("requestType"));
			bean.setCreatedBy(request.getHeader("createdBy"));
			bean.setServiceId(request.getHeader("serviceId"));
			bean.setChecksum(request.getHeader("checksum"));
			bean.setFileSize(request.getHeader("fileSize"));
			bean.setLastAttempt(request.getHeader("lastAttempt"));
			bean.setLinkSecret(request.getHeader("linkSecret"));
			bean.setFilename(request.getHeader("filename"));
			bean.setCreateDate(request.getHeader("createDate"));
			bean.setServiceDate(request.getHeader("serviceDate"));
			bean.setTaskId(request.getHeader("taskId"));
			bean.setRemoteAddr(request.getHeader("remoteAddr"));
		}
		ASCLogger.info(this.getClass(), methodName, "File Upload Bean:" + bean);
		return bean;
	}
}
